package com.xyj.zjbz.interceptor;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.xyj.zjbz.constants.Constants;
import com.xyj.zjbz.po.ZJDataSource;
import com.xyj.zjbz.po.User;
import com.xyj.zjbz.user.service.UserService;
import com.xyj.zjbz.util.DataSourceSwitcher;
import com.xyj.zjbz.util.DynamicDataSource;
import com.xyj.zjbz.util.DynamicLoadBean;
import com.xyj.zjbz.util.XMLUtils;

/**
 * session中不存在userId，则重定向到登陆页面
 * 
 * @author 李朝衡
 * 
 */
public class LoginInterceptor implements HandlerInterceptor {
	@Autowired
	Constants constants;
	@Autowired
	UserService userService;
	/**
	 * 用于加载新的bean、到spring容器
	 * 
	 */
	@Autowired
	DynamicLoadBean loadBean;
	@Autowired
	DynamicDataSource dataSources;
	/**
	 * 获取context
	 */
	@Autowired
	ApplicationContext context;

	private final Logger log = Logger.getLogger(LoginInterceptor.class
			.getName());
	private String loginPage; // 登录界面

	public void setLoginPage(String loginPage) {
		this.loginPage = loginPage;
	}

	/**
	 * preHandle方法是进行处理器拦截用的，顾名思义，该方法将在Controller处理之前进行调用，
	 * SpringMVC中的Interceptor拦截器是链式的，可以同时存在
	 * 多个Interceptor，然后SpringMVC会根据声明的前后顺序一个接一个的执行
	 * ，而且所有的Interceptor中的preHandle方法都会在
	 * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的
	 * ，这种中断方式是令preHandle的返 回值为false，当preHandle的返回值为false的时候整个请求就结束了。
	 */
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		// TODO Auto-generated method stub
		String uri = request.getRequestURI();
		StringBuffer urid = request.getRequestURL();
		log.info("uri：" + uri);
		log.info("url：" + urid.toString());
		uri = uri.substring(uri.indexOf("/", 1), uri.length());
		if (uri.equals("/user/toAddDs")) {
			return true;
		}
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		String path = LoginInterceptor.class.getClassLoader()
				.getResource("dynamic").getPath();
		if (user == null) {// 没有
			log.info("session's user is null, now redirect to login page");
			response.sendRedirect(request.getContextPath() + loginPage);
			return false;
		} else {
			// 数据源切换
			log.info("判断数据源...");
			Integer sysId = user.getSysId();
			ZJDataSource bz = userService.getBZSystemById(sysId);// 默认切换回defaultDateSource
			try {
				File f = new File(path + bz.getBzDB() + ".xml");
				if (!f.exists()) {
					// 读取datasource xml模板信息(dynamic/dataSourceCfgTempl.vm)
					XMLUtils.createXMLByTemp(bz);
					// 加载bean
					loadBean.loadBean("classpath:dynamic/" + bz.getBzDB()
							+ ".xml");
					Object ds = context.getBean(bz.getBzDB());
					// 添加dataSource
					dataSources.addDataSource(bz.getBzDB(), ds);
				}
				log.info("切换数据源:" + bz.getBzDB());
				DataSourceSwitcher.setDataSource(bz.getBzDB());

			} catch (Exception e) {
				e.printStackTrace();
			}
			return true;
		}
	}

	/**
	 * postHandle：后处理回调方法，实现处理器的后处理（但在渲染视图之前），此时我们可以通过modelAndView（模型和视图对象）
	 * 对模型数据进行处理或对视图进行处理，modelAndView也可能为null
	 */
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		if (modelAndView != null) {
			modelAndView.addObject("currenTime", new SimpleDateFormat(
					"yyyy-MM-dd HH:mm:ss").format(new Date()));
		}
	}

	/**
	 * afterCompletion：整个请求处理完毕回调方法，即在视图渲染完毕时回调，如性能监控中我们可以在此记录结束时间并输出消耗时间，
	 * 还可以进行一些资源清理，类似于try-catch-finally中的finally，
	 * 但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。
	 */
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub

	}

}
